package com.xinqi.common.green.utils;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.green.model.v20180509.TextScanRequest;
import com.aliyuncs.http.FormatType;
import com.aliyuncs.http.HttpResponse;
import com.xinqi.common.green.enums.GreenScanSuggestionEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 阿里云 -- 文本反垃圾检测
 * <p>
 * 参数文档说明：
 * https://help.aliyun.com/document_detail/70292.htm?spm=a2c4g.53424.0.0.470f3b87paTKPt#reference-fzy-ztm-v2b
 *
 * @Author：yyzhen
 * @Package：com.xinqi.common.base.utils.green
 * @Project：xinqiclass-cloud-plus
 * @name：GreenTextUtils
 * @Date：2023/4/18 17:53
 * @Filename：GreenTextUtils
 */
@Slf4j
public class GreenTextUtils extends SyncScan {

    /**
     * 设置要检测的风险场景。计费依据此处传递的场景计算。
     * 指定检测场景，取值：antispam，表示文本内容检测。
     */
    private static final List<String> scenes = Arrays.asList("antispam");

    /**
     * 同步检测 -- 文本反垃圾检测
     * <p>
     * 批量操作
     * <p>
     * map中data为传入的原始数据
     * 若违规，则返回处理结果
     * filteredContent
     *
     * @Title:
     * @MethodName: textScan
     * [textList]
     * @Return java.util.List<java.util.Map < java.lang.String, java.lang.String>>
     * @Exception
     * @Description:
     * @author: yyzhen
     * @date: 2023/4/18 18:13
     */
    public static List<Map<String, String>> textScan(List<String> textList) {
        if (CollectionUtil.isEmpty(textList)) {
            return null;
        }
        List<Map<String, Object>> tasks = new ArrayList<Map<String, Object>>();

        for (String text : textList) {
            if (StringUtils.isEmpty(text)) {
                continue;
            }
            JSONObject task = new JSONObject();
            //待检测的文本，长度不超过10000个字符
            task.put("content", text);
            tasks.add(task);
        }
        JSONObject data = new JSONObject();
        data.put("bizType", BIZ_TYPE);
        //检测场景。文本垃圾检测请传递antispam。
        data.put("scenes", scenes);
        data.put("tasks", tasks);

        try {
            return textSyncScan(data);
        } catch (Exception e) {
            log.error("文本反垃圾检测同步检测异常，请检查配置信息", e);
            return null;
        }

    }

    /**
     * 同步检测 -- 文本反垃圾检测
     * <p>
     * 单个操作
     * <p>
     * map中data为传入的原始数据
     *
     * @Title:
     * @MethodName: textScan
     * [textList]
     * @Return java.util.Map < java.lang.String, java.lang.String>
     * @Exception
     * @Description:
     * @author: yyzhen
     * @date: 2023/4/18 18:13
     */
    public static Map<String, String> textScan(String text) {
        if (StringUtils.isEmpty(text)) {
            return null;
        }
        List<Map<String, Object>> tasks = new ArrayList<Map<String, Object>>();

        JSONObject task = new JSONObject();
        //待检测的文本，长度不超过10000个字符。
        task.put("content", text);
        tasks.add(task);
        JSONObject data = new JSONObject();
        data.put("bizType", BIZ_TYPE);
        // 检测场景。文本垃圾检测请传递antispam。
        data.put("scenes", scenes);
        data.put("tasks", tasks);

        try {
            List<Map<String, String>> result = textSyncScan(data);
            if (CollectionUtil.isEmpty(result)) {
                return null;
            }
            return result.get(0);
        } catch (Exception e) {
            log.error("文本反垃圾检测同步检测异常，请检查配置信息", e);
            return null;
        }

    }

    /**
     * 同步文本反垃圾检测方法(返回检测不通过的)
     */
    private static List<Map<String, String>> textSyncScan(JSONObject data) {
        List<Map<String, String>> resultList = new ArrayList<>();
        try {
            IAcsClient client = new DefaultAcsClient(getProfile());

            TextScanRequest textScanRequest = new TextScanRequest();
            //指定API返回格式。
            textScanRequest.setAcceptFormat(FormatType.JSON);
            textScanRequest.setHttpContentType(FormatType.JSON);
            //指定请求方法。
            textScanRequest.setMethod(com.aliyuncs.http.MethodType.POST);
            textScanRequest.setEncoding("UTF-8");
            textScanRequest.setRegionId("cn-shanghai");
            textScanRequest.setHttpContent(data.toJSONString().getBytes("UTF-8"), "UTF-8", FormatType.JSON);
            //请务必设置超时时间。
            textScanRequest.setConnectTimeout(connectTimeout);
            textScanRequest.setReadTimeout(readTimeout);

            HttpResponse httpResponse = client.doAction(textScanRequest);
            if (!httpResponse.isSuccess()) {
                log.info("response not success. status:" + httpResponse.getStatus());
                // 业务处理。
                return resultList;
            }
            JSONObject scrResponse = JSON.parseObject(new String(httpResponse.getHttpContent(), "UTF-8"));
            //log.info(JSON.toJSONString(scrResponse, true));
            if (200 != scrResponse.getInteger("code")) {
                log.info("detect not success. code:" + scrResponse.getInteger("code"));
                // 业务处理。
                return resultList;
            }
            JSONArray taskResults = scrResponse.getJSONArray("data");
            for (Object taskResult : taskResults) {
                int taskCode = ((JSONObject) taskResult).getIntValue("code");
                JSONArray sceneResults = ((JSONObject) taskResult).getJSONArray("results");
                String content = ((JSONObject) taskResult).getString("content");
                Map<String, String> resultMap = new HashMap<>();
                resultMap.put("data", content);
                if (200 == taskCode) {
                    //默认为校验通过
                    resultMap.put("suggestion", GreenScanSuggestionEnum.PASS.getCode());
                    for (Object sceneResult : sceneResults) {
                        String suggestion = ((JSONObject) sceneResult).getString("suggestion");
                        //存在一个场景违规就是违规
                        if (Objects.equals(GreenScanSuggestionEnum.BLOCK.getCode(), suggestion)) {
                            resultMap.put("suggestion", GreenScanSuggestionEnum.BLOCK.getCode());
                            //违规处理后的文字
                            String filteredContent = ((JSONObject) sceneResult).getString("filteredContent");
                            resultMap.put("filteredContent", filteredContent);
                            //场景
                            String label = ((JSONObject) sceneResult).getString("label");
                            resultMap.put("label", label);
                        }
                    }
                } else {
                    log.error("task process fail. task response:" + JSON.toJSONString(taskResult));
                    //默认为校验通过
                    resultMap.put("suggestion", GreenScanSuggestionEnum.REVIEW.getCode());
                }
                resultList.add(resultMap);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("文本反垃圾同步检测方法异常", e);
        }
        return resultList;
    }

}
